<!-- 搜索组件 -->
<template>
  <div class="dt-search">
    <Form ref="formRef" :model="info" :label-width="labelWidth" :label-colon="true" @submit.native.prevent>
      <Row :gutter="12" :key="rowKey">
        <Col
          v-if="opt.visible != false"
          v-for="(opt, index) in options"
          :key="index"
          :xl="opt.xl || xl"
          :sm="12"
          :md="8"
          :lg="8">
          <dt-info-item ref="itemRef" :option="opt" :info="info" @change="onChange" />
        </Col>

        <!-- 按钮 -->
        <Col :xl="xlBtn" :sm="20" :md="10" :lg="10" v-if="showBtn">
          <FormItem :label-width="5" class="handle-btn">
            <Button @click="reset">重置</Button>
            <Button type="primary" @click="onSearch">搜索</Button>
            <slot></slot>
          </FormItem>
        </Col>
      </Row>
    </Form>
  </div>
</template>

<script setup>
  import { watch, ref } from 'vue'
  import dtInfo from '@/components/dt/info'
  const props = defineProps({
    modelValue: Object,
    value: Object,
    items: Array,
    labelWidth: { type: Number, default: 80 },
    xl: { type: Number, default: 6 },
    xlBtn: { type: Number, default: 8 },
    showBtn: {
      type: Boolean,
      default: true
    }
  })
  const emits = defineEmits(['update:modelValue', 'reset', 'search', 'change'])

  const [itemRef, formRef] = [ref(), ref()]
  const [initInfo, info, options] = [ref(), ref(), ref([])]
  const [tableRef, rowKey] = [ref(), ref(1)]

  function init(table, opt, inf = {}) {
    tableRef.value = table
    updateOptions(opt.options ? opt.options() : opt)
    info.value = inf
    initInfo.value = { ...inf }
    tableRef.value.searchInfo = info.value
  }

  function clear() {
    return new Promise((resolve, reject) => {
      let items = itemRef.value?.option ? [itemRef.value] : itemRef.value || []
      items.forEach((item) => {
        let val = initInfo.value[item.option.key]
        if (val == null || val.length == 0) item.clear()
      })
      setTimeout(() => {
        for (let key in info.value) {
          info.value[key] = initInfo.value[key] || null
        }
        if (tableRef.value) tableRef.value.searchInfo = info.value
        emits('update:modelValue', info.value)
        resolve()
      }, 500)
    })
  }

  function reset() {
    rowKey.value++
    formRef.value.resetFields()
    clear().then((res) => {
      emits('reset')
      tableRef.value?.search()
    })
  }

  function onSearch() {
    formRef.value.validate((valid) => {
      if (valid) {
        console.log(info.value, 'klk')
        emits('search', info.value)
        tableRef.value?.search()
      }
    })
  }

  function updateOptions(items) {
    options.value = (items || []).map((item) => {
      if (item.rules) item.rules = item.rules.filter((i) => !i.required)
      return item
    })
  }

  function onChange() {
    emits('change')
  }

  watch(
    () => props.items,
    (n) => updateOptions(n),
    { immediate: true }
  )

  watch(
    () => props.modelValue,
    (n) => {
      info.value = n
    },
    { immediate: true }
  )

  watch(
    () => props.value,
    (n) => {
      info.value = n
    },
    { immediate: true }
  )

  defineExpose({
    init,
    clear,
    reset,
    update(opt, inf) {
      let opts = opt.options ? opt.options() : opt
      inf = inf ? { ...initInfo.value, ...inf } : tableRef.value?.searchInfo
      updateOptions(opts)
      info.value = dtInfo.validInfo(inf, opts)
      if (tableRef.value) tableRef.value.searchInfo = info.value
      rowKey.value++
    }
  })
</script>

<style lang="scss" scoped>
  .handle-btn {
    ::v-deep button {
      margin-right: 8px;
    }
  }
</style>
